﻿package game.ui {
	import game.objects.GameObject;
	import game.objects.DynamicObject;
	import game.debug.Debug;
	import game.objects.DynamicElement;
	import game.events.DynamicClipEvent;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	import flash.utils.setTimeout;
	import flash.utils.clearTimeout;
	
	public class DynamicClip extends GameObject {
		
		public var container:MovieClip;
		public var back:MovieClip;
		
		private var maska:MovieClip;
		private var wrap:MovieClip;
		private var center:MovieClip;
		private var top:MovieClip;
		private var bottom:MovieClip;
		private var left:MovieClip;
		private var right:MovieClip;
		private var data:DynamicObject;
		private var test:Boolean;
		private var interval;
		
		public function DynamicClip(data:DynamicObject) {
			this.data = data;
			
			if (!this.data) {
				debug("Не найден DynamicObject в "+getQualifiedClassName(this), Debug.INTERFACE);
				return;
			}
			
			wrap		= new MovieClip;
			back		= new MovieClip;
			container	= new MovieClip;
			maska		= new MovieClip;
			center		= new MovieClip;
			top			= new MovieClip;
			bottom		= new MovieClip;
			left		= new MovieClip;
			right		= new MovieClip;
			
			back.addChild(center);
			back.addChild(top);
			back.addChild(bottom);
			back.addChild(left);
			back.addChild(right);
			
			wrap.addChild(back);
			wrap.addChild(container);
			wrap.addChild(maska);
			
			super.addChild(wrap);
			
			//проверяем дебаг ли
			for each (var d:String in config.debug) {
				if (d==Debug.DYNAMIC_OBJECTS) {
					test = true;
					break;
				}
			}
			
			if (!test)
				container.mask = maska;
			else 
				maska.mouseEnabled = maska.mouseEnabled = false;
				
			//создаем краи
			if (data.top)
				top.addChild(getBitmap(data.top));
			if (data.bottom)
				bottom.addChild(getBitmap(data.bottom));
			if (data.left)
				left.addChild(getBitmap(data.left));
			if (data.right)
				right.addChild(getBitmap(data.right));
			
			createElements();
			
			this.addEventListener(Event.ADDED_TO_STAGE, added);
		}
		
		private function createElements():void {
			//создаем элементы на сцене
			if (!data.elements) return;
			for each (var el:DynamicElement in data.elements) {
				if (getDefinitionByName(el.classString)) {
					var _class:Class = getDefinitionByName(el.classString) as Class;
					var _object:DisplayObject = new _class;
					_object.name = el.name;
					addChild(_object);
					if (el.params.filters)
						_object.filters = el.params.filters;
					switch (el.type) {
						case DynamicElement.TYPE_TEXT:
							//if (el.params.align) (_object as Text).align = el.params.align;
							if (el.params.size)
								(_object as Text).setFormat("size", el.params.size);
							
							(_object as Text).addEventListener(Event.CHANGE, update);
						break;
					}
					el.data = _object;
					
				}
			}
		}
		
		private function added(event:Event):void { 
			stage.addEventListener(Event.RESIZE, update); update(null);
		}
		
		public override function addChild(object:DisplayObject):DisplayObject {
			try {
				container.addChild(object);
			} catch (e:Error) {
				Debug.log("Ошибка создания элементов в DynamicClip", Debug.INTERFACE);
			}
			return object;
		}
		
		private function update(event:Event):void {
			this.alpha = 0;
			clearTimeout(interval);
			
			this.dispatchEvent( new DynamicClipEvent ( DynamicClipEvent.START_RESIZE ) );
			
			interval = setTimeout(resized, config.updateDynamic*1000);
		}
		
		private function resized():void {
			//закрашиваем весь stage, если hide
			
			animate('alpha', this.alpha, 1, 0.1);
			
			if (data.hide) {
				with (this.graphics) {
					clear();
					beginFill(0x000000, config.hideBeginAlpha);
					drawRect(0, 0, stage.stageWidth, stage.stageHeight);
					endFill();
				}
			}
			//если указана ширина, растягиваем
			if (data.width)
				centerWidth = parseLength(data.width, stage.stageWidth);
			//если указана высота, растягиваем
			if (data.height)
				centerHeight = parseLength(data.height, stage.stageHeight);
			//если не указана ни ширина, ни высота, вставляем один объект
			if (!data.width && !data.height)
				centerWidth = data.center.width;
			//размещаем краи, относительно центра
			top.x		= (center.width - top.width)/2;
			top.y		= - top.height;
			bottom.x	= (center.width - bottom.width)/2;
			bottom.y	= center.height;
			left.x		= -left.width;
			left.y		= (center.height - left.height)/2;
			right.x		= center.width;
			right.y		= (center.height - right.height)/2;
			//размещаем wrap
			setWrapX();
			setWrapY();
			//размещаем контейнер и маску
			container.x = maska.x = parseLength(data.conainerLeft, center.width);
			container.y = maska.y = parseLength(data.conainerTop, center.height);
			//рисуем маску для контейнера
			with (maska.graphics) {
				clear();
				if (test)
					lineStyle(1, 0xff0000);
				beginFill(0x000000, (test ? 0 : 1));
				var widthMask:Number = -maska.x + center.width + parseLength(data.conainerRight, center.width);
				var heightMask:Number = -maska.y + center.height + parseLength(data.conainerBottom, center.height);
				drawRect(0, 0, widthMask, heightMask);
				endFill();
			}
			
			//elements resize
			var elementLength:Number;
			for each (var el:DynamicElement in data.elements) {
				if (!el.data) continue;
				
				elementLength = parseLength(el.params.x, width);
				if (elementLength<0) elementLength = width + elementLength;
				el.data.x = elementLength;
				elementLength = parseLength(el.params.y, height);
				if (elementLength<0) elementLength = height + elementLength;
				el.data.y = elementLength;
				switch (el.type) {
					case DynamicElement.TYPE_TEXT:
						switch (el.params.align) {
							case Text.CENTER:
								(el.data as Text).x = el.data.x + ((el.params.width ? parseLength(el.params.width, width) : width) - el.data.width)/2;
							break;
						}
					break;
					case DynamicElement.TYPE_SLIDER:
						if (el.params.width) el.data.width = (parseLength(el.params.width, width)>=0) ? (parseLength(el.params.width, width)) : (width+parseLength(el.params.width, width)-el.data.x);
						if (el.params.height) el.data.height = (parseLength(el.params.height, height)>=0) ? (parseLength(el.params.height, height)) : (height+parseLength(el.params.height, height)-el.data.y);
						
					break;
				}
			}
			
			this.dispatchEvent( new DynamicClipEvent ( DynamicClipEvent.END_RESIZE ) );
			
		}
		
		private function setWrapX():void {
			if (data.x == DynamicObject.POSITION_RIGHT) {
				wrap.x = stage.stageWidth - center.width - (data.right ? data.right.width : 0);
			} else if (data.x == DynamicObject.POSITION_CENTER) {
				wrap.x = (stage.stageWidth - back.width)/2 + (data.right ? data.right.width : 0);
			} else {
				var xLength:Number = parseLength(data.x, stage.stageWidth);
				if (xLength<0) xLength = stage.stageWidth + xLength;
				wrap.x = xLength + (data.left ? data.left.width : 0);
			}
		}
		
		private function setWrapY():void {
			if (data.y == DynamicObject.POSITION_BOTTOM) {
				wrap.y = stage.stageHeight - back.height - (data.bottom ? data.bottom.height : 0);
			} else if (data.y == DynamicObject.POSITION_CENTER) {
				wrap.y = (stage.stageHeight - back.height)/2 + (data.bottom ? data.bottom.height : 0);
			} else {
				var yLength:Number = parseLength(data.y, stage.stageHeight);
				if (yLength<0) yLength = stage.stageHeight + yLength;
				wrap.y = yLength + (data.top ? data.top.height : 0);
			}
		}
		
		private function set centerWidth(value:Number):void {
			clearCenter();
			var bitmap:Bitmap;
			if (data.left) 
				value -= data.left.width;
			if (data.right)
				value -= data.right.width;
			if (value<data.center.width) value = data.center.width;
			while (center.width<value) {
				bitmap = getBitmap(data.center);
				bitmap.x = center.width;
				center.addChild(bitmap);
			}
			if (center.width>value)
				bitmap.width = bitmap.width - (center.width-value);
		}
		
		private function set centerHeight(value:Number):void {
			clearCenter();
			var bitmap:Bitmap;
			if (data.top) 
				value -= data.top.width;
			if (data.bottom)
				value -= data.bottom.width;
			if (value<data.center.height) value = data.center.height;
			while (center.height<value) {
				bitmap = getBitmap(data.center);
				bitmap.y = center.height;
				center.addChild(bitmap);
			}
			if (center.height>value)
				bitmap.height = bitmap.height - (center.height-value);
		}
		
		private function clearCenter():void {
			while (center.numChildren)
				center.removeChildAt(0);
		}
		
		public override function get width():Number {
			return maska.width;
		}
		
		public override function get height():Number {
			return maska.height;
		}
		
		public override function getChildByName(value:String):DisplayObject {
			return container.getChildByName(value);
		}
		
		private function getBitmap(bitmapData:BitmapData):Bitmap {
			var bitmap:Bitmap = new Bitmap(bitmapData);
			return bitmap;
		}
		
		private function parseLength(value:String, max:Number):Number {
			var length:Number = 0;
			if (!value) return length;
			if (value.indexOf('%')>=0) {
				length = parseInt (value.substr(0, value.indexOf('%')));
				length = length * max / 100;
			} else if (value.indexOf('px')>=0) { 
				length = parseInt (value.substr(0, value.indexOf('px')));
			}
			return length;
		}
		
		public function close():void {
			try {
				this.parent.removeChild(this);
			} catch (e:Error) {
				trace (e.message);
			}
		}
		
	}
}
